#ifndef utility_StlContainer_Iterator_h
#define utility_StlContainer_Iterator_h

#include "Iterator.h"
#include <vector>

namespace serika
{
	namespace ut
	{
		template<typename Container, typename Item>
		class StlContainerReadOnlyIterator : public ReadOnlyIterator<Item>
		{
		public:
			StlContainerReadOnlyIterator(const Container& itemList);
			virtual ~StlContainerReadOnlyIterator() {}

		public:
			virtual bool HasNext() const;
			virtual void Next();

		protected:
			typename Container::const_iterator mCurrent;
			typename Container::const_iterator mEnd;
		};

		template<typename Container, typename Item>
		StlContainerReadOnlyIterator<Container, Item>::StlContainerReadOnlyIterator(const Container& itemList)
			: mCurrent(itemList.begin())
			, mEnd(itemList.end())
		{
		}

		template<typename Container, typename Item>
		bool StlContainerReadOnlyIterator<Container, Item>::HasNext() const
		{
			return mCurrent != mEnd;
		}

		template<typename Container, typename Item>
		void StlContainerReadOnlyIterator<Container, Item>::Next()
		{
			++mCurrent;
		}

		// ------------------------------------------------------------------------------------------------

		template<typename Container, typename Item>
		class StlContainerIterator : public Iterator<Item>
		{
		public:
			StlContainerIterator(Container& itemList);
			virtual ~StlContainerIterator() {}

		public:
			virtual bool HasNext() const;
			virtual void Next();

		protected:
			typename Container::iterator mCurrent;
			typename Container::iterator mEnd;
		};

		template<typename Container, typename Item>
		StlContainerIterator<Container, Item>::StlContainerIterator(Container& itemList)
			: mCurrent(itemList.begin())
			, mEnd(itemList.end())
		{
		}

		template<typename Container, typename Item>
		bool StlContainerIterator<Container, Item>::HasNext() const
		{
			return mCurrent != mEnd;
		}

		template<typename Container, typename Item>
		void StlContainerIterator<Container, Item>::Next()
		{
			++mCurrent;
		}
	}
}

#endif
